<html>
    <head>
        <title>控制类和方法的工作单元</title>
    </head>
    <body>
        <script>
            /*
                        三、控制类、方法工作单元  Controlling the Unit Of Work

                                   在某些情况下，你可能希望更改常规事务范围、创建内部范围或精细控制事务行为。以下部分涵盖了这些可能性。

                                   1、IUnitOfWorkEnable接口  

                                                这是一种简单的方法，可以为不是上面解释的约定的工作单元的类（或类的层次结构）启用UOW。

                                                eg: 为任意服务实现IUnitOfWorkEnabled

                                                    using System.Threading.Tasks;
                                                    using Volo.Abp.DependencyInjection;
                                                    using Volo.Abp.Uow;

                                                    namespace AbpDemo
                                                    {
                                                        // 实现IUnitOfWorkEnabled接口后，该类所有方法都将在一个UOW作用域内执行。
                                                        public class MyService : ITransientDependency, IUnitOfWorkEnabled 
                                                        {
                                                            // 方法必须为虚方法，才能在"非注入"情况下启用UOW。
                                                            // 方法必须为异步方法，否则UOW无法工作。
                                                            public virtual async Task FooAsync()
                                                            {
                                                                // 此方法将在一个UOW作用域内执行。
                                                            }
                                                        }
                                                    }
                                                
                                                然后MyService（以及从中派生的任何类）方法将是UOW。

                                                但是，应该遵循一些规则才能使其工作：

                                                        ①、如果你没有通过接口注入服务(eg: IMyService) ,则该服务的方法必须是 virtual 否则，动态代理/拦截系统无法工作）。

                                                        ②、只有async方法（返回Task或Task<T>的方法）被拦截。因此，同步方法不能启动UOW。

                                                        
                                                （请注意，如果在UOW范围内调用了FooAsync，则它已经参与到UOW中，而不需要IUnitOfWorkEnabled或任何其他配置。）

                                    2、[UnitOfWork] 特性   

                                            (1)、如何使用[UnitOfWork]特性为类、方法启用UOW？

                                                        [UnitOfWork]特性提供了更多的可能性，例如启用或禁用UOW以及控制事务行为。

                                                        [UnitOfWork]特性可用于"类" 或 "方法" 级别。

                                                        eg： 为类的特定方法启用UOW
                                                                    
                                                            using System.Threading.Tasks;
                                                            using Volo.Abp.DependencyInjection;
                                                            using Volo.Abp.Uow;

                                                            namespace AbpDemo
                                                            {
                                                                public class MyService : ITransientDependency
                                                                {
                                                                    [UnitOfWork]  // 使用特性为方法启用UOW
                                                                    public virtual async Task FooAsync()  // 注意，必须是async方法，必须是virtual方法 否则无法启用UOW
                                                                    {
                                                                        //this is a method with a UOW scope
                                                                    }
                                                                    
                                                                    public virtual async Task BarAsync()
                                                                    {
                                                                        //this is a method without UOW
                                                                    }
                                                                }
                                                            }

                                                    
                                                        eg: 为类的所有方法启用UOW

                                                            using System.Threading.Tasks;
                                                            using Volo.Abp.DependencyInjection;
                                                            using Volo.Abp.Uow;

                                                            namespace AbpDemo
                                                            {
                                                                [UnitOfWork]  // 使用特性为类启用UOW
                                                                public class MyService : ITransientDependency
                                                                {
                                                                    public virtual async Task FooAsync() // 注意，必须是async方法，必须是virtual方法 否则无法启用UOW
                                                                    {
                                                                        //this is a method with a UOW scope
                                                                    }
                                                                    
                                                                    public virtual async Task BarAsync()
                                                                    {
                                                                        //this is a method with a UOW scope
                                                                    }
                                                                }
                                                            }

                                                    ★、同样，相同的规则在这里有效：

                                                            ①、如果你没有通过接口注入服务（如IMyService），则服务的方法必须是virtual（否则，动态代理/拦截系统无法工作）。

                                                            ②、只有async方法（返回Task或Task<T>的方法）被拦截。因此，同步方法不能启动UOW。



                                            (2)、[UnitOfWork]特性的的属性   [UnitOfWorkAttribute] Properties 

                                                        ①、IsTransactional（bool?）：用于设置UOW是否应该是事务性的。默认值为null。如果你让它null，它会根据约定和配置自动确定。

                                                        ②、TimeOut（int?）：用于设置此UOW的超时值。默认值为null并回退到默认配置值。

                                                        ③、IsolationLevel（IsolationLevel?）：用于设置数据库事务的隔离级别，如果UOW是事务性的。如果未设置，则使用默认配置值。

                                                        ④、IsDisabled（bool）：用于禁用当前方法/类的UOW。

                                        ★、 
                                            (如果一个方法在UOW作用域内部调用，那么它自身的[UnitOfWork]特性将被忽略，它自动加入调用者的UOW作用域。
                                            
                                              被调用的方法不再开启新的UOW作用域。)           

                                                        eg: 为控制器操作禁用UOW

                                                                using System.Threading.Tasks;
                                                                using Volo.Abp.AspNetCore.Mvc;
                                                                using Volo.Abp.Uow;

                                                                namespace AbpDemo.Web
                                                                {
                                                                    public class MyController : AbpController
                                                                    {
                                                                        [UnitOfWork(IsDisabled = true)]   // 禁用该action的UOW
                                                                        public virtual async Task FooAsync()
                                                                        {
                                                                            //...
                                                                        }
                                                                    }
                                                                }
                    */
        </script>
    </body>
</html>